#include "poller.h"
#include "unistd.h"

#include "global_env.h"
#include <string.h>

Poller::Poller(){
    epollFd_ = epoll_create(LISTENQ);
}

Poller::~Poller(){
    close(epollFd_);
}

void Poller::Poll(std::vector<Channel*>& channels){
    int events_num = epoll_wait(epollFd_, &*epollEvents_.begin(), MAXEVENTS, -1); 
    if (events_num < 0 && errno != EINTR) {
        return ;
    }
    for(int i=0; i<events_num; ++i){
        Channel* channel = static_cast<Channel*>(epollEvents_[i].data.ptr);
        channel->SetREvents(epollEvents_[i].events);
        channels.push_back(channel);
    }
}

void Poller::UpdateChannel(Channel* channel)
{
    int fd = channel->GetFd();

    if(channelMap_.find(fd)==channelMap_.end()){
        Update(EPOLL_CTL_ADD, channel);
    }else{
        Update(EPOLL_CTL_MOD, channel);
    }
    channelMap_[fd] = channel;
}

void Poller::RemoveChannel(Channel* channel)
{
    Update(EPOLL_CTL_DEL, channel);
    channelMap_.erase(channel->GetFd());
}

void Poller::Update(int operation, Channel* channel)
{
    struct epoll_event event;
    memset(&event, 0, sizeof(event));
    event.events = channel->GetEvents();
    event.data.ptr = channel;
    int fd = channel->GetFd();

    epoll_ctl(epollFd_, operation, fd, &event);
}